package com.zq.assistant.func.okhttp;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CountDownLatch;

/**
 * Created by zhangqiang on 17-6-6.
 */

public class SpeedCompute extends HandlerThread implements Handler.Callback{

    private Handler handler;
    private final Map<SpeedFileTransferListener,TransferInfo> transferInfoMap = new HashMap<>();
    private static final SpeedCompute instance = new SpeedCompute();
    private CountDownLatch countDownLatch = new CountDownLatch(1);

    public static SpeedCompute getInstance(){
        return instance;
    }

    private SpeedCompute() {
        super("speed-count");
        start();
    }

    @Override
    protected void onLooperPrepared() {
        super.onLooperPrepared();
        handler = new Handler(this);
        countDownLatch.countDown();
    }

    @Override
    public boolean handleMessage(Message msg) {

        synchronized (transferInfoMap){

            if(transferInfoMap.isEmpty()){
                return true;
            }

            for (Map.Entry<SpeedFileTransferListener,TransferInfo> entry:
                 transferInfoMap.entrySet()) {

                TransferInfo transferInfo = entry.getValue();

                SpeedFileTransferListener fileTransferListener = entry.getKey();

                long speed = transferInfo.computeSpeed();

                Log.i("Test",fileTransferListener + "========computeSpeed======" + speed + "====fileTransferListener size===" + transferInfoMap.size());

                fileTransferListener.onSpeedChange(speed);

            }
            handler.sendEmptyMessageDelayed(0,1000);
        }
        return true;
    }


    void update(SpeedFileTransferListener fileTransferListener, long currentLength){

        if(handler == null){

            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        if(handler == null){
            return;
        }

        synchronized (transferInfoMap){

            final boolean isPreviousEmpty = transferInfoMap.isEmpty();

            TransferInfo transferInfo = transferInfoMap.get(fileTransferListener);
            if(transferInfo == null){
                transferInfo = new TransferInfo();
                transferInfoMap.put(fileTransferListener,transferInfo);
            }

            transferInfo.currentLength = currentLength;

            if(isPreviousEmpty){

                handler.sendEmptyMessageDelayed(0,1000);
            }
        }
    }

    void finish(SpeedFileTransferListener fileTransferListener){

        synchronized (transferInfoMap){
            transferInfoMap.remove(fileTransferListener);
        }
    }

    private static class TransferInfo{

        private long lastLength;

        private long lastTime = System.currentTimeMillis();

        private long currentLength;

        long computeSpeed(){

            long deltaLength = currentLength - lastLength;
            long currentTime = System.currentTimeMillis();
            long deltaTime   = currentTime - lastTime;
            long speed        = deltaTime == 0 ? 0 : (long) (deltaLength / (deltaTime / 1000f));
            lastLength       = currentLength;
            lastTime         = currentTime;
            return speed;
        }
    }
}
